package com.wxscrmplus.web.controller.customer;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.wxscrmplus.common.annotation.Log;
import com.wxscrmplus.common.annotation.RepeatSubmit;
import com.wxscrmplus.common.core.controller.BaseController;
import com.wxscrmplus.common.core.domain.PageQuery;
import com.wxscrmplus.common.core.domain.R;
import com.wxscrmplus.common.core.page.TableDataInfo;
import com.wxscrmplus.common.core.validate.AddGroup;
import com.wxscrmplus.common.core.validate.EditGroup;
import com.wxscrmplus.common.enums.BusinessType;
import com.wxscrmplus.common.enums.QueryDataRange;
import com.wxscrmplus.common.excel.ExcelResult;
import com.wxscrmplus.common.utils.ServletUtils;
import com.wxscrmplus.common.utils.poi.ExcelUtil;
import com.wxscrmplus.customer.domain.FollowUser;
import com.wxscrmplus.customer.domain.bo.*;
import com.wxscrmplus.customer.domain.excel.CustomerImportExcel;
import com.wxscrmplus.customer.domain.vo.*;
import com.wxscrmplus.customer.listener.SyncCustomerImportListener;
import com.wxscrmplus.customer.mapper.CustomerMapper;
import com.wxscrmplus.customer.mapper.FollowUserMapper;
import com.wxscrmplus.customer.service.*;
import com.wxscrmplus.drainage.domain.bo.DraChannelBo;
import com.wxscrmplus.drainage.domain.vo.DraChannelVo;
import com.wxscrmplus.drainage.service.IDraChannelService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 客户
 *
 * @author 王永超
 * @date 2023-03-24
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/customer/customer")
public class CustomerController extends BaseController {

    private final ICustomerService iCustomerService;


    private final IFollowUserService iFollowUserService;
    private final FollowUserMapper followUserMapper;

    private final ICusTypeService iCusTypeService;

    private final IDraChannelService iDraChannelService;
    private final ICusMaintainService iCusMaintainService;
    private final IFollowRecordService iFollowRecordService;
    private final IOpportunityService iOpportunityService;
    private final IContactService iContactService;
    private final CustomerMapper customerMapper;
    private final ICustomerLogService iCustomerLogService;

    /**
     * 同步企微客户
     */
    @SaIgnore
    @PostMapping("/syncExternalContact")
    public R<Void> syncExternalContact() {
        iCustomerService.syncExternalContact();
        return R.ok();
    }

    /**
     * 回显客户选择器值
     *
     * @param customerIds 主键串
     */
    @SaIgnore
    @GetMapping("/echoSelect/{customerIds}")
    public R<List<CustomerVo>> echoSelect(@NotEmpty(message = "主键不能为空")
                                          @PathVariable Long[] customerIds) {
        List<CustomerVo> list = customerMapper.selectVoBatchIds(Arrays.asList(customerIds));
        return R.ok(list);
    }

    /**
     * 获客渠道全部数据列表
     */
    @SaCheckPermission("customer:customer:list")
    @GetMapping("/channe/channeDropDown")
    public TableDataInfo<DraChannelVo> channeDropDown(DraChannelBo bo) {
        List<DraChannelVo> list = iDraChannelService.queryList(bo);
        return TableDataInfo.build(list);
    }

    /**
     * 查询客户类型列表
     */
    @SaCheckPermission("customer:customer:list")
    @GetMapping("/type/typeDropDown")
    public TableDataInfo<CusTypeVo> typeDropDown(CusTypeBo bo) {
        List<CusTypeVo> list = iCusTypeService.queryList(bo);
        return TableDataInfo.build(list);
    }

    /**
     * 查询客户列表
     */
    @SaCheckPermission("customer:customer:list")
    @GetMapping("/list")
    public TableDataInfo<CustomerVo> list(CustomerBo bo, PageQuery pageQuery) {
        List<Long> userIds = Collections.singletonList(getUserId());
        String queryDataRange = ServletUtils.getParameter("queryDataRange");
        if (StrUtil.isNotBlank(queryDataRange)) {
            if (queryDataRange.equals(QueryDataRange.BENBUMENDE.getValue())) {
                StpUtil.checkPermission("customer:customer:list:dept");
                userIds = getDeptUserIds();
            } else if (queryDataRange.equals(QueryDataRange.SUOYOUDE.getValue())) {
                StpUtil.checkPermission("customer:customer:list:all");
                userIds = getAllUserIds();
            }
        }
        bo.setDataRangeUserIds(userIds);
        return iCustomerService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出客户列表
     */
    @SaCheckPermission("customer:customer:export")
    @Log(title = "客户", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(CustomerBo bo, HttpServletResponse response) {
        List<CustomerVo> list = iCustomerService.queryList(bo);
        ExcelUtil.exportExcel(list, "客户", CustomerVo.class, response);
    }

    /**
     * 获取客户详细信息
     *
     * @param customerId 主键
     */
    @SaCheckPermission("customer:customer:query")
    @GetMapping("/{customerId}")
    public R<CustomerVo> getInfo(@NotNull(message = "主键不能为空")
                                 @PathVariable Long customerId) {
        return R.ok(iCustomerService.queryById(customerId));
    }

    /**
     * 新增客户
     */
    @SaCheckPermission("customer:customer:add")
    @Log(title = "客户", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping()
    public R<Void> add(@Validated(AddGroup.class) @RequestBody CustomerBo bo) {
        return toAjax(iCustomerService.insertByBo(bo));
    }

    /**
     * 修改客户
     */
    @SaCheckPermission("customer:customer:edit")
    @Log(title = "客户", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping()
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody CustomerBo bo) {
        return toAjax(iCustomerService.updateByBo(bo));
    }

    /**
     * 转让跟进人
     */
    @SaCheckPermission("customer:followUser:transfer")
    @PostMapping("/transfer")
    public R<Void> transferCustomer(@RequestBody CustomerTransferBo customerTransferBo) {
        customerTransferBo.setOut(getUserId());
        iCustomerService.transferCustomer(customerTransferBo);
        return R.ok();
    }

    /**
     * 删除客户
     *
     * @param customerIds 主键串
     */
    @SaCheckPermission("customer:customer:remove")
    @Log(title = "客户", businessType = BusinessType.DELETE)
    @DeleteMapping("/{customerIds}")
    public R<Void> remove(@NotEmpty(message = "主键不能为空")
                          @PathVariable Long[] customerIds) {
        return toAjax(iCustomerService.deleteWithValidByIds(Arrays.asList(customerIds), true));
    }


    /**
     * 修改企微信息
     */
    @SaCheckPermission("customer:customer:edit")
    @Log(title = "跟进成员", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/followUser")
    public R<Void> followUserEdit(@Validated(EditGroup.class) @RequestBody FollowUserBo bo) {
        return toAjax(iFollowUserService.updateByBo(bo));
    }


    /**
     * 根据客户ID获取（自己）跟进成员详细信息
     *
     * @param customerId 客户ID
     */
    @SaCheckPermission("customer:customer:query")
    @GetMapping("/followUser/myself/{customerId}")
    public R<FollowUserVo> followUserGetFollow(@NotNull(message = "客户ID不能为空")
                                               @PathVariable Long customerId) {
        FollowUserVo followUserVo = followUserMapper.selectVoOne(Wrappers.query(new FollowUser()).lambda().eq(FollowUser::getCustomerId, customerId)
            .eq(FollowUser::getUserId, this.getUserId()));
        return R.ok(followUserVo);
    }

    //-------------------跟进人---------------------------------

    /**
     * 查询跟进成员列表
     */
    @SaCheckPermission("customer:customer:followUser:list")
    @GetMapping("/followUser/list")
    public TableDataInfo<FollowUserVo> followUserList(FollowUserBo bo, PageQuery pageQuery) {
        return iFollowUserService.queryPageList(bo, pageQuery);
    }

    //----------------维护-------------------------

    /**
     * 查询客户维护全部数据列表
     */
    @SaCheckPermission(value = {"customer:customer:maintain:listAll"}, mode = SaMode.OR)
    @GetMapping("/maintain/listAll")
    public TableDataInfo<CusMaintainVo> maintainListAll(CusMaintainBo bo) {
        return TableDataInfo.build(iCusMaintainService.queryList(bo));
    }

    /**
     * 查询客户维护列表
     */
    @SaCheckPermission(value = {"customer:customer:maintain:list"}, mode = SaMode.OR)
    @GetMapping("/maintain/list")
    public TableDataInfo<CusMaintainVo> maintainList(CusMaintainBo bo, PageQuery pageQuery) {
        List<Long> dataRangeUserIds = Collections.singletonList(getUserId());
        String queryDataRange = ServletUtils.getParameter("queryDataRange");
        if (StrUtil.isNotBlank(queryDataRange)) {
            if (queryDataRange.equals(QueryDataRange.BENBUMENDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:dept");
                dataRangeUserIds = getDeptUserIds();
            } else if (queryDataRange.equals(QueryDataRange.SUOYOUDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:all");
                dataRangeUserIds = getAllUserIds();
            }
        }
        bo.setDataRangeUserIds(dataRangeUserIds);
        return iCusMaintainService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出客户维护列表
     */
    @SaCheckPermission(value = {"customer:customer:maintain:export"}, mode = SaMode.OR)
    @Log(title = "客户维护", businessType = BusinessType.EXPORT)
    @PostMapping("/maintain/export")
    public void maintainExport(CusMaintainBo bo, HttpServletResponse response) {
        List<CusMaintainVo> list = iCusMaintainService.queryList(bo);
        ExcelUtil.exportExcel(list, "客户维护", CusMaintainVo.class, response);
    }

    /**
     * 获取客户维护详细信息
     *
     * @param maintainId 主键
     */
    @SaCheckPermission(value = {"customer:customer:maintain:query", "customer:maintain:edit"}, mode = SaMode.OR)
    @GetMapping("/maintain/{maintainId}")
    public R<CusMaintainVo> maintainGetInfo(@NotNull(message = "主键不能为空")
                                            @PathVariable Long maintainId) {
        return R.ok(iCusMaintainService.queryById(maintainId));
    }

    /**
     * 新增客户维护
     */
    @SaCheckPermission(value = {"customer:customer:maintain:add"}, mode = SaMode.OR)
    @Log(title = "客户维护", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/maintain")
    public R<Void> maintainAdd(@Validated(AddGroup.class) @RequestBody CusMaintainBo bo) {
        bo.setUserId(getUserId());
        return toAjax(iCusMaintainService.insertByBo(bo));
    }

    /**
     * 修改客户维护
     */
    @SaCheckPermission(value = {"customer:customer:maintain:edit"}, mode = SaMode.OR)
    @Log(title = "客户维护", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/maintain")
    public R<Void> maintainEdit(@Validated(EditGroup.class) @RequestBody CusMaintainBo bo) {
        return toAjax(iCusMaintainService.updateByBo(bo));
    }

    /**
     * 删除客户维护
     *
     * @param maintainIds 主键串
     */
    @SaCheckPermission(value = {"customer:customer:maintain:remove"}, mode = SaMode.OR)
    @Log(title = "客户维护", businessType = BusinessType.DELETE)
    @DeleteMapping("/maintain/{maintainIds}")
    public R<Void> maintainRemove(@NotEmpty(message = "主键不能为空")
                                  @PathVariable Long[] maintainIds) {
        return toAjax(iCusMaintainService.deleteWithValidByIds(Arrays.asList(maintainIds), true));
    }

    //--------------------跟进记录------------------------------

    /**
     * 查询跟进记录列表
     */
    @SaCheckPermission("customer:customer:followRecord:list")
    @GetMapping("/followRecord/list")
    public TableDataInfo<FollowRecordVo> followRecordList(FollowRecordBo bo, PageQuery pageQuery) {
        List<Long> dataRangeUserIds = Collections.singletonList(getUserId());
        String queryDataRange = ServletUtils.getParameter("queryDataRange");
        if (StrUtil.isNotBlank(queryDataRange)) {
            if (queryDataRange.equals(QueryDataRange.BENBUMENDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:dept");
                dataRangeUserIds = getDeptUserIds();
            } else if (queryDataRange.equals(QueryDataRange.SUOYOUDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:all");
                dataRangeUserIds = getAllUserIds();
            }
        }
        bo.setDataRangeUserIds(dataRangeUserIds);
        return iFollowRecordService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出跟进记录列表
     */
    @SaCheckPermission("customer:customer:followRecord:export")
    @Log(title = "跟进记录", businessType = BusinessType.EXPORT)
    @PostMapping("/followRecord/export")
    public void followRecordExport(FollowRecordBo bo, HttpServletResponse response) {
        List<FollowRecordVo> list = iFollowRecordService.queryList(bo);
        ExcelUtil.exportExcel(list, "跟进记录", FollowRecordVo.class, response);
    }

    /**
     * 获取跟进记录详细信息
     *
     * @param followRecordId 主键
     */
    @SaCheckPermission("customer:customer:followRecord:query")
    @GetMapping("/followRecord/{followRecordId}")
    public R<FollowRecordVo> followRecordGetInfo(@NotNull(message = "主键不能为空")
                                                 @PathVariable Long followRecordId) {
        return R.ok(iFollowRecordService.queryById(followRecordId));
    }

    /**
     * 新增跟进记录
     */
    @SaCheckPermission("customer:customer:followRecord:add")
    @Log(title = "跟进记录", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/followRecord")
    public R<Void> followRecordAdd(@Validated(AddGroup.class) @RequestBody FollowRecordBo bo) {
        bo.setUserId(getUserId());
        return toAjax(iFollowRecordService.insertByBo(bo));
    }

    /**
     * 修改跟进记录
     */
    @SaCheckPermission("customer:customer:followRecord:edit")
    @Log(title = "跟进记录", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/followRecord")
    public R<Void> followRecordEdit(@Validated(EditGroup.class) @RequestBody FollowRecordBo bo) {
        return toAjax(iFollowRecordService.updateByBo(bo));
    }

    /**
     * 删除跟进记录
     *
     * @param followRecordIds 主键串
     */
    @SaCheckPermission("customer:customer:followRecord:remove")
    @Log(title = "跟进记录", businessType = BusinessType.DELETE)
    @DeleteMapping("/followRecord/{followRecordIds}")
    public R<Void> followRecordRemove(@NotEmpty(message = "主键不能为空")
                                      @PathVariable Long[] followRecordIds) {
        return toAjax(iFollowRecordService.deleteWithValidByIds(Arrays.asList(followRecordIds), true));
    }

    //-----------------------销售机会----------------------------


    /**
     * 查询销售机会列表
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:list"}, mode = SaMode.OR)
    @GetMapping("/opportunity/list")
    public TableDataInfo<OpportunityVo> opportunityList(OpportunityBo bo, PageQuery pageQuery) {
        List<Long> dataRangeUserIds = Collections.singletonList(getUserId());
        String queryDataRange = ServletUtils.getParameter("queryDataRange");
        if (StrUtil.isNotBlank(queryDataRange)) {
            if (queryDataRange.equals(QueryDataRange.BENBUMENDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:dept");
                dataRangeUserIds = getDeptUserIds();
            } else if (queryDataRange.equals(QueryDataRange.SUOYOUDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:all");
                dataRangeUserIds = getAllUserIds();
            }
        }
        bo.setDataRangeUserIds(dataRangeUserIds);
        return iOpportunityService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出销售机会列表
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:export"}, mode = SaMode.OR)
    @Log(title = "销售机会", businessType = BusinessType.EXPORT)
    @PostMapping("/opportunity/export")
    public void opportunityExport(OpportunityBo bo, HttpServletResponse response) {
        List<OpportunityVo> list = iOpportunityService.queryList(bo);
        ExcelUtil.exportExcel(list, "销售机会", OpportunityVo.class, response);
    }

    /**
     * 获取销售机会详细信息
     *
     * @param opportunityId 主键
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:query", "customer:customer:opportunity:edit"}, mode = SaMode.OR)
    @GetMapping("/opportunity/{opportunityId}")
    public R<OpportunityVo> opportunityGetInfo(@NotNull(message = "主键不能为空")
                                               @PathVariable Long opportunityId) {
        return R.ok(iOpportunityService.queryById(opportunityId));
    }

    /**
     * 新增销售机会
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:add"}, mode = SaMode.OR)
    @Log(title = "销售机会", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/opportunity")
    public R<Void> opportunityAdd(@Validated(AddGroup.class) @RequestBody OpportunityBo bo) {
        bo.setSaleId(getUserId());
        return toAjax(iOpportunityService.insertByBo(bo));
    }

    /**
     * 修改销售机会
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:edit"}, mode = SaMode.OR)
    @Log(title = "销售机会", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/opportunity")
    public R<Void> opportunityEdit(@Validated(EditGroup.class) @RequestBody OpportunityBo bo) {
        return toAjax(iOpportunityService.updateByBo(bo));
    }

    /**
     * 删除销售机会
     *
     * @param opportunityIds 主键串
     */
    @SaCheckPermission(value = {"customer:customer:opportunity:remove"}, mode = SaMode.OR)
    @Log(title = "销售机会", businessType = BusinessType.DELETE)
    @DeleteMapping("/opportunity/{opportunityIds}")
    public R<Void> opportunityRemove(@NotEmpty(message = "主键不能为空")
                                     @PathVariable Long[] opportunityIds) {
        return toAjax(iOpportunityService.deleteWithValidByIds(Arrays.asList(opportunityIds), true));
    }
    //----------------------联系方式------------------------

    /**
     * 查询联系方式列表
     */
// 4b366c6f598e0729f3fef926f1ec1154
    @SaCheckPermission("customer:customer:contact:list")
    @GetMapping("/contact/list")
    public TableDataInfo<ContactVo> contactList(ContactBo bo, PageQuery pageQuery) {
        List<Long> dataRangeUserIds = Collections.singletonList(getUserId());
        String queryDataRange = ServletUtils.getParameter("queryDataRange");
        if (StrUtil.isNotBlank(queryDataRange)) {
            if (queryDataRange.equals(QueryDataRange.BENBUMENDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:dept");
                dataRangeUserIds = getDeptUserIds();
            } else if (queryDataRange.equals(QueryDataRange.SUOYOUDE.getValue())) {
                StpUtil.checkPermission("customer:customer:followUser:list:all");
                dataRangeUserIds = getAllUserIds();
            }
        }
        bo.setDataRangeUserIds(dataRangeUserIds);
        return iContactService.queryPageList(bo, pageQuery);
    }

    /**
     * 导出联系方式列表
     */
    @SaCheckPermission("customer:customer:contact:export")
    @Log(title = "联系方式", businessType = BusinessType.EXPORT)
    @PostMapping("/contact/export")
    public void contactExport(ContactBo bo, HttpServletResponse response) {
        List<ContactVo> list = iContactService.queryList(bo);
        ExcelUtil.exportExcel(list, "联系方式", ContactVo.class, response);
    }

    /**
     * 获取联系方式详细信息
     *
     * @param contactId 主键
     */
    @SaCheckPermission("customer:customer:contact:query")
    @GetMapping("/contact/{contactId}")
    public R<ContactVo> contactGetInfo(@NotNull(message = "主键不能为空")
                                       @PathVariable Long contactId) {
        return R.ok(iContactService.queryById(contactId));
    }

    /**
     * 新增联系方式
     */
    @SaCheckPermission("customer:customer:contact:add")
    @Log(title = "联系方式", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @PostMapping("/contact")
    public R<Void> contactAdd(@Validated(AddGroup.class) @RequestBody ContactBo bo) {
        bo.setUserId(getUserId());
        return toAjax(iContactService.insertByBo(bo));
    }

    /**
     * 修改联系方式
     */
    @SaCheckPermission("customer:customer:contact:edit")
    @Log(title = "联系方式", businessType = BusinessType.UPDATE)
    @RepeatSubmit()
    @PutMapping("/contact")
    public R<Void> contactEdit(@Validated(EditGroup.class) @RequestBody ContactBo bo) {
        return toAjax(iContactService.updateByBo(bo));
    }

    /**
     * 删除联系方式
     *
     * @param contactIds 主键串
     */
    @SaCheckPermission("customer:customer:contact:remove")
    @Log(title = "联系方式", businessType = BusinessType.DELETE)
    @DeleteMapping("/contact/{contactIds}")
    public R<Void> contactRemove(@NotEmpty(message = "主键不能为空")
                                 @PathVariable Long[] contactIds) {
        return toAjax(iContactService.deleteWithValidByIds(Arrays.asList(contactIds), true));
    }

    /**
     * 导入数据
     *
     * @param file 导入文件
     */
    @Log(title = "客户管理", businessType = BusinessType.IMPORT)
    @SaCheckPermission("customer:customer:import")
    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
        ExcelResult<CustomerImportExcel> result = ExcelUtil.importExcel(file.getInputStream(), CustomerImportExcel.class, new SyncCustomerImportListener());
        return R.ok(result.getAnalysis());
    }

    /**
     * 获取导入模板
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ArrayList<CustomerImportExcel> example = new ArrayList<>();
        ExcelUtil.exportExcel(example, "客户数据", CustomerImportExcel.class, response);
    }

    /**
     * 查询客户日志列表
     */
    @SaCheckPermission(value = {"customer:customer:customerLog:list"}, mode = SaMode.OR)
    @GetMapping("/customerLog/list")
    public TableDataInfo<CustomerLogVo> list(CustomerLogBo bo, PageQuery pageQuery) {
        return iCustomerLogService.queryPageList(bo, pageQuery);
    }

}
